<?php

namespace app\common\service;

class Token
{

    public function __construct()
    {
        $this->redis = initRedis();
    }

    /**
     * 通过uid获取token
     * @param int $uid
     * @return int
     */
    public function getToken(int $uid): array
    {
        $key = config('token.prefix') . 'uids:' . $uid;
        $rs = $this->redis->Zrange($key, 0, -1);
        return $rs;
    }

    public function getValue(string $token): array
    {
        $key = config('token.prefix') . 'token:' . $token;
        $rs = $this->redis->get($key);
        if ($rs) {
            $val = json_decode($rs, true);
        } else {
            $val = [];
        }
        return $val;
    }

    /**
     * 设置token
     * @param int $uid
     * @param array $value 需要存储的值
     * @return array
     */
    public function setToken(int $uid, array $value = []): array
    {
        $token = md5($uid . '@' . time() . '#' . rand(1000, 9999));
        $this->redis->MULTI();
        //token存入用户uid有续集合
        $expire = intval(time() + config('token.expire'));
        $keySet = config('token.prefix') . 'uids:' . $uid;
        $this->redis->zadd($keySet, $expire, $token);

        //redis设置token
        $key = config('token.prefix') . 'token:' . $token;
        $value['uid'] = $uid;
        $value['logintime'] = date('Y-m-d H:i:s');
        $value['expire'] = date('Y-m-d H:i:s', $expire);
        $this->redis->setex($key, config('token.expire'), json_encode($value));
        $this->redis->EXEC();
        $value['token'] = $token;
        return $value;
    }

    /**
     * 删除token
     * @param string $token
     */
    public function deleteToken(string $token): bool
    {

        $key = config('token.prefix') . 'token:' . $token;
        $value = $this->getValue($token);
        if ($value) {
            $keySet = config('token.prefix') . 'uids:' . $value['uid'];
            $this->redis->MULTI();
            $this->redis->zrem($keySet, $token);
            $this->redis->del($key);
            $this->redis->EXEC();
            return true;
        } else {
            return false;
        }
    }
}